<?php

namespace app\award;

use app\models\order\Order;
use app\models\order\OrderItem;
use app\models\product\Product;
use app\models\product\ProductAreaList;
use app\models\Queue;
use app\models\QueueRepeat;
use app\models\QueueScanPay;
use app\models\QueueScanPayPool;
use app\models\SetProductCommission;
use app\models\SetUserUp;
use app\models\user\User;
use app\models\user\UserAccount;
use app\models\user\UserAddress;
use app\models\user\UserCommission;
use app\models\user\UserLevel;
use app\models\UserBalance;
use app\models\UserStore;
use app\models\UserStoreLog;
use app\services\Chain;
use yii\helpers\ArrayHelper;

class Award
{
    protected $user;
    protected $order;
    protected $set;

    protected $items;

    // 总金额
    protected $amount;

    // 复购商品单价
    protected $price;

    // 复购数量
    protected $box;

    protected $is_bao = false;
    protected $is_repeat = false;

    // 是否为重算订单
    protected $is_reset = false;


    public function __construct(Order $order, $is_reset = false)
    {
        $this->order = $order;
        $this->user = User::findOne(['id' => $order->user_id]);
        $this->set = SetUserUp::getLastOne();

        $this->is_reset = $is_reset;

        $this->items = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->all();

        $first_order_item = OrderItem::find()
            ->where(['order_id' => $this->order->id])
            ->orderBy(['id' => SORT_ASC])
            ->limit(1)
            ->one();
        $product_id = $first_order_item->product_id;

        // 复购商品价格
        $this->price = Product::find()
            ->select(['price'])
            ->where(['id' => $product_id])
            ->scalar();

        $this->amount = $this->order->total_pay - $this->order->total_freight;

        // 报单区
        $this->is_bao = ProductAreaList::checkInArea($product_id, Product::$areaMap['REPORT']);
        if ($this->is_bao) {
            $this->bao();
            $this->vip2($product_id);
        }

        // 复购区
        $this->is_repeat = ProductAreaList::checkInArea($product_id, Product::$areaMap['REPEAT']);
        if ($this->is_repeat) {
            $this->order->is_repeat = 1;
            $this->order->save();
            $this->repeat();
            $this->queue();
        }

        // 收银区
        $is_money = ProductAreaList::checkInArea($product_id, Product::$areaMap['MONEY']);
        if ($is_money) {
            $this->money();
        }

        // 收银操作
        if ($this->order->supplier_id > 0) {
            $this->scanPay();
        }
    }

    public function scanPay()
    {
        $real_amount = 0;

        // 1) 商家结算
        $merchant = User::findOne(['id' => $this->order->supplier_id]);
        if ($merchant) {
            $commission = $this->amount * (1 - $merchant->discount / 100);
            $this->saveCommission($merchant->id, $commission, '201', '线下扫码支付');

            $real_amount = $this->amount - $commission;
        }

        // 2) 排队
        $queue = new QueueScanPay();
        $queue->user_id = $this->order->user_id;
        $queue->merchant_id = $this->order->supplier_id;
        $queue->order_id = $this->order->id;
        $queue->amount = $this->order->total_pay;
        $queue->status = 0;
        $queue->real_amount = $real_amount;
        $queue->save();

        $result = QueueScanPayPool::findOne(['merchant_id' => $queue->merchant_id]);
        if (!$result) {
            $result = new QueueScanPayPool();
            $result->amount = $real_amount;
            $result->merchant_id = $queue->merchant_id;
        } else {
            $result->amount += $real_amount;
        }
        $result->save();

        // 3) 返回
        $the_first = QueueScanPay::find()
            ->where(['merchant_id' => $queue->merchant_id])
            ->andWhere(['status' => 0])
            ->orderBy(['id' => SORT_ASC])
            ->one();
        if ($the_first) {
            if ($result->amount >= $the_first->amount) {
                $result->amount -= $the_first->amount;
                $the_first->status = 1;
                $the_first->save();
                $result->save();

                $this->saveCommission($the_first->user_id, $the_first->amount, '202', '全返');
            }
        }
    }

    public function money()
    {
        $this->user->discount = $this->order->discount;
        $this->user->save();

        $this->order->status = Order::$statusMapping['FINISH'];
        $this->order->save();
    }

    // 配额超级经理
    public function vip2($product_id)
    {
        $num = (int) Product::find()
            ->where(['id' => $product_id])
            ->select(['with1'])
            ->scalar();
        if ($num > 0) {
            $account = UserAccount::findOne(['user_id' => $this->user->id]);
            $account->vip2 += $num;
            $account->save();
        }
    }

    // 第几单
    private function isFirstOrder($user_id)
    {
        $children = Chain::getChildren($user_id);
        $children = ArrayHelper::getColumn($children, 'id');

        $sum = (int) Order::find()
            ->where(['user_id' => $children])
            ->andWhere(['!=', 'status', Order::$statusMapping['NON_PAYMENT']])
            ->andWhere(['!=', 'status', Order::$statusMapping['CANCEL']])
            ->andWhere(['!=', 'status', Order::$statusMapping['DELETE']])
            ->andWhere(['!=', 'status', Order::$statusMapping['REFUND']])
            ->andWhere(['total_price' => $this->set->vip1])
            ->count();

        return $sum <= 1;
    }

    // 报单
    public function bao()
    {
        $r = Chain::getReferrer($this->user->id, true);
        if (!$r || $r->level < UserLevel::$keys['vip1']) {
            return;
        }

        $name1 = '推荐奖';
        $type1 = 11;
        $name2 = '团队奖';
        $type2 = 12;

        if ($this->amount == $this->set->vip1) {
            $first = $this->isFirstOrder($r->id);

            // 推荐奖
            if ($r->level > UserLevel::$keys['vip1']) {
                $commission = $this->set->vip1_2;
            } else {
                if ($first) {
                    $commission = $this->set->vip1_1;
                } else {
                    $commission = $this->set->vip1_2;
                }
            }
            $this->saveCommission($r->id, $commission, $type1, $name1);

            // 团队奖
            $chain = Chain::getReferrerChain($this->user->id, [
                UserLevel::$keys['vip2'],
                UserLevel::$keys['vip3'],
                UserLevel::$keys['vip4'],
            ], true);
            if ($chain) {
                $user = $chain[0];
                if ($first) {
                    $commission = $this->set->vip_1_balance;
                    $score = $this->set->vip_1_score;
                } else {
                    $commission = $this->set->vip_2_balance;
                    $score = 0;
                }
                $this->saveCommission($user->id, $commission, $type2, $name2, $score);
            }
        }
    }


    public function repeat()
    {
        // todo 这里可以不要搞这么复杂
        if ($this->amount < $this->set->repeat_price) {
            return;
        }

        // 团队奖
        $chain = Chain::getReferrerChain($this->user->id, [
            UserLevel::$keys['vip2'],
            UserLevel::$keys['vip3'],
            UserLevel::$keys['vip4'],
        ], true);
        // if ($chain) {
        //     $user = $chain[0];
        //     $commission = $this->set->team_ratio / 100 * $this->amount;
        //     $this->saveCommission($user->id, $commission, '20', '复购团队奖');
        // }

        $name = '复购团队奖';
        $type = '20';

        $has_vip2 = false;
        $has_vip3 = false;
        $has_vip4 = false;

        $ratio = $this->set->team_ratio / 100;
        $commission = $this->amount;

        foreach ($chain as $user) {
            if (!$has_vip2 && !$has_vip3 && !$has_vip4 && $user->level == UserLevel::$keys['vip2']) {
                $commission *= $ratio;
                $this->saveCommission($user->id, $commission, $type, $name);
                $has_vip2 = true;
            }
            if (!$has_vip3 && !$has_vip4 && $user->level == UserLevel::$keys['vip3']) {
                $commission *= $ratio;
                $this->saveCommission($user->id, $commission, $type, $name);
                $has_vip3 = true;
            }
            if (!$has_vip4 && $user->level == UserLevel::$keys['vip4']) {
                $commission *= $ratio;
                $this->saveCommission($user->id, $commission, $type, $name);
                $has_vip4 = true;
                break;
            }
        }


    }

    public function queue()
    {

        // 检测有没有参与3次, 并且中奖
        $counter = (int) QueueRepeat::find()
            ->where(['user_id' => $this->order->user_id])
            ->andWhere(['status' => 2])
            ->count();
        if ($counter >= $this->set->repeat_num) {
            return;
        }

        // 排队
        $model = new QueueRepeat();
        $model->user_id = $this->order->user_id;
        $model->order_id = $this->order->id;
        $model->status = 0;
        $model->save();

        // 抽奖[0 表示未处理]
        $list = QueueRepeat::find()
            ->andWhere(['status' => 0])
            ->orderBy(['id' => SORT_ASC])
            ->all();

        if (count($list) >= 10) {
            foreach ($list as $key => $queue) {
                if ($key == 0) {
                    // 第1位中奖
                    $queue->status = 2;
                } else {
                    $queue->status = 1;
                }
                $queue->save();
            }

        }
    }

    // 保存佣金 (await balance)
    protected function saveCommission($user_id, $balance, $type, $name, $score = 0, $status = 1)
    {
        if ($balance >= 0.01) {
            $model = new UserCommission();
            $model->user_id = $user_id;
            $model->fans_id = $this->order->user_id;
            $model->order_id = $this->order->id;
            $model->balance = $balance;
            $model->score = $score;
            $model->status = $status;
            $model->award_name = $name;
            $model->award_type = $type;
            $model->save();
            $account = UserAccount::findOne(['user_id' => $user_id]);

            if ($account) {
                if ($status == 1) {
                    $account->balance += $balance;
                    $account->score += $score;
                } else {
                    $account->await_balance += $balance;
                }

              $account->save();
            }

            // balance logs
            if ($status == 1) {
                UserBalance::addLog($model->user_id,
                    $account->balance, $model->balance, $account->balance + $model->balance, '返佣', $this->order->id);
            }

            return true;
        }
    }

}